//
//  Message.swift
//  JKTools
//
//  Created by 姜奎 on 2/19/25.
//

import Foundation
import CoreData

public struct Message: Codable {
    enum Sender:String, Codable {
        case user
        case guest
    }
    let id: String
    let sessionId: String
    var content: Data
    var timestamp = Date()
    let sender: Sender

    static func helloAi(by sessionId: String) -> Message {
        return Message(id: UUID().uuidString, sessionId: sessionId, content: "Hello Ai!".toData()!, timestamp: Date(), sender: .guest)
    }
}

public struct Session: Codable, Equatable {
    let id: String
    let timestamp: Date
    let groupText: String
    let title: String

    public static func == (lhs: Session, rhs: Session) -> Bool {
        lhs.id == rhs.id
    }

    static func helloAi() -> Session {
        let sessionId = UUID().uuidString
        let timestamp = Date()
        return Session(id: sessionId, timestamp: timestamp, groupText: timestamp.formattedCalendarTime, title: "新会话")
    }
}

public struct SessionGroup {
    let title: String
    var sessions: [Session]

    static func helloAi() -> SessionGroup {
        return SessionGroup(title: Date().formattedCalendarTime, sessions: [.helloAi()])
    }
}

extension Date {
    var formattedTodayTime: String {
        let formatter = DateFormatter()
        if Calendar.current.isDateInToday(self) {
            formatter.dateStyle = .none
            formatter.timeStyle = .medium
        } else {
            formatter.doesRelativeDateFormatting = true
            formatter.dateStyle = .short
            formatter.timeStyle = .medium
        }
        return formatter.string(from: self)
    }

    var formattedCalendarTime: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter.string(from: self)
    }
}

class AiProvider: JKCoreDataProvider {
    override func momdName() -> String {
        return "AiModel"
    }

    override func momdBundle() -> Bundle {
        return Bundle.main
    }

    override func persistentStoreType() -> String {
//        return NSInMemoryStoreType
        return NSSQLiteStoreType
    }

    override func fetchRequest<SessionEntity>() -> NSFetchRequest<SessionEntity> {
        let fetchRequest = NSFetchRequest<SessionEntity>(entityName: "SessionEntity")
//        fetchRequest.returnsObjectsAsFaults = true
        fetchRequest.predicate = NSPredicate(value: true)
        let titleSortDescriptor = NSSortDescriptor(key: "groupText", ascending: false)
        let timestampSortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
        fetchRequest.sortDescriptors = [titleSortDescriptor, timestampSortDescriptor]
            //        每次查询返回总条目
        fetchRequest.fetchLimit = Int(INT_MAX)
            //        分批加载数据 每批个数，fetchBatchSize > fetchLimit 时 毫无意义
        fetchRequest.fetchBatchSize = Int(INT_MAX)
            //        返回数据的偏移量，一般用于分批查询
            //        fetchRequest.fetchOffset = 300
        return fetchRequest
    }

    func fetchMessageRequest(by sessionId: String) -> NSFetchRequest<MessageEntity> {
        let fetchRequest = NSFetchRequest<MessageEntity>(entityName: "MessageEntity")
            //        fetchRequest.returnsObjectsAsFaults = true
        fetchRequest.predicate =  NSPredicate(format: "sessionId == %@", sessionId)
        let timestampSortDescriptor = NSSortDescriptor(key: "timestamp", ascending: true)
        fetchRequest.sortDescriptors = [timestampSortDescriptor]
            //        每次查询返回总条目
        fetchRequest.fetchLimit = Int(INT_MAX)
            //        分批加载数据 每批个数，fetchBatchSize > fetchLimit 时 毫无意义
        fetchRequest.fetchBatchSize = Int(INT_MAX)
            //        返回数据的偏移量，一般用于分批查询
//                    fetchRequest.fetchOffset = 0
        return fetchRequest
    }

    static let shared = AiProvider()
}

class AiStack: JKCoreDataStack {
    private override init(_ provider: JKCoreDataProvider) throws {
        try super.init(provider)
    }

    static let shared = try! AiStack(AiProvider.shared)

    @MainActor
    lazy var fetchedResultController: NSFetchedResultsController<SessionEntity>? = {
        guard let fetch: NSFetchedResultsController<SessionEntity> = try? AiStack.shared.fetchedResultController(sectionNameKeyPath: #keyPath(SessionEntity.groupText)) else {
            return nil
        }
        return fetch
    }()

    @MainActor
    func messageFetchedResultController(by sessionId: String) -> NSFetchedResultsController<MessageEntity>? {
        return try? AiStack.shared.fetchedResultController(fetchRequest: AiProvider.shared.fetchMessageRequest(by: sessionId))
    }
}
